package net.oschina.aibinxiao.security.Hmac;

import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * @Author: AiBinXiao
 * @Description: MAC消息认证码算法的几种算法的实现
 * @Date: 2017/10/13 15:02
 */

public class MyHmac {
    private static String src = "imooc security hmac";

    public static void main(String[] args) {
        jdkHmacMD5();
        bcHmacMD5();
    }

    // 1.HmacMD5算法的JDK实现
    public static void jdkHmacMD5() {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5"); // 初始化KeyGenerator
            SecretKey secretKey = keyGenerator.generateKey(); // 产生密钥
            //byte[] key = secretKey.getEncoded(); // 获得自动生成的密钥

            byte[] key = Hex.decodeHex(new char[] {'a','a','a','a','a','a','a','a','a','a'}); // 自定义密钥

            // 还原密钥
            SecretKey restoreSecretKey = new SecretKeySpec(key, "HmacMD5"); // 还原密钥
            Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm()); // 实例化MAC
            mac.init(restoreSecretKey); // 初始化Mac
            byte[] hmacMD5Bytes = mac.doFinal(src.getBytes());
            System.out.println("JDK HmacMD5 : " + Hex.encodeHexString(hmacMD5Bytes));
            // JDK HmacMD5 : 8873a00b0cc8198d489d13593c6a0fb9
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 2.HmacMD5算法的Bouncy Castle实现
    public static void bcHmacMD5() {
        HMac hMac = new HMac(new MD5Digest());
        hMac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex.decode("aaaaaaaaaa")));
        hMac.update(src.getBytes(), 0, src.getBytes().length);

        byte[] hMacMD5Bytes = new byte[hMac.getMacSize()]; // 执行消息摘要
        hMac.doFinal(hMacMD5Bytes, 0);
        System.out.println("Bouncy Castle HmacMD5 : " + org.bouncycastle.util.encoders.Hex.toHexString(hMacMD5Bytes));
        // Bouncy Castle HmacMD5 : 522b5217700cdcedd73f19bd67bad599
    }
}
